package com.profgj.profgj.controller;

import com.profgj.profgj.entity.User;
import com.profgj.profgj.entity.UserNotify;
import com.profgj.profgj.enums.ServerStatus;
import com.profgj.profgj.service.UserNotifyService;
import com.profgj.profgj.service.UserService;
import com.profgj.profgj.utils.EmptyUtils;
import com.profgj.profgj.utils.ReturnOperator;
import com.profgj.profgj.validater.UserVoValidator;
import com.profgj.profgj.vo.EmptyObject;
import com.profgj.profgj.vo.ResultMsg;
import com.profgj.profgj.vo.UserVo;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * (用户管理)表控制层
 *
 * @author 杨帅
 * @since 2021-06-22 11:09:35
 */

/**
 * 标注该类为控制器
 */
@Controller
@Api(tags = {"用户登录注册"},description = "用户登录注册")
public class LoginController {

    /**
     * 用户服务对象
     */
    @Resource
    private UserService userService;

    /**
     * 用户通知服务对象
     */
    @Resource
    private UserNotifyService userNotifyService;

    /**
     * 将配置文件中system.user.password.secret 中的值 注入到secret成员变量中
     */
    @Value("${system.user.password.secret}")
    private String secret = null;

    /**
     * 返回空对象的替代品
     */
    private EmptyObject emptyObject = new EmptyObject();

    /**
     * 初始化设置校验器
     * @param binder    校验器绑定对象
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.setValidator(new UserVoValidator());
    }

    /**
     * 导航到首页
     *
     */
    @GetMapping(value = {"/","/index"})
    @ApiOperation(value = "导航到首页")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public String index(@ApiIgnore HttpSession session){
        // 从登录成功的认证对象中获取用户名称
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 用户名查询出用户全部信息
        User user = userService.queryUserByName(authentication.getName());
        // 添加到Session中被以后接口的参数使用
        session.setAttribute("user_id",user.getId());
        session.setAttribute("role_id",user.getRoleId());
        session.setAttribute("user_name",user.getUsername());
        session.setAttribute("jltj",user.getJltj());
        // 企业用户通知对象 企业用户一用户只有一条通知
        UserNotify userNotify = null;
        // 管理员通知list 管理员有多条通知
        List<UserNotify> userNotifies = null;
        if (user.getRoleId() != 1){
            userNotify = userNotifyService.queryByEnUserIdAndRead(user.getId(),0);
            if(EmptyUtils.isUserNotifyEmpty(userNotify)){
                // 企业用户是notify
                session.setAttribute("notify",userNotify);
                session.setAttribute("size",1);
            }else {
                session.setAttribute("notify",userNotify);
                session.setAttribute("size",0);
            }
        }else {
            userNotifies = userNotifyService.queryByAdminUserId(user.getId(), 0);
            if (EmptyUtils.isUserNotifyListEmpty(userNotifies)){
                // 管理员是notifys
                session.setAttribute("size",userNotifies.size());
            }else {
                // 管理员是notifys
                session.setAttribute("size",0);
            }

        }

        return "index";
    }

    @GetMapping(value = {"/content"})
    @ApiOperation(value = "导航到首页内容")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public String content(){

        return "content";
    }

    /**
     * 登录失败页面
     * 这里使用了RequestMapping 通用处理器不然 post的验证码 Get接收不到
     * @param request
     * @return
     */
    @RequestMapping("/fail")
    @ApiOperation(value = "登录失败页面")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public String failPage(HttpServletRequest request) {

        // 从请求中获取错误码
        String err_code = String.valueOf(request.getAttribute("err_code"));
        // 验证码为空了
        if ("1".equalsIgnoreCase(err_code)) {
            request.setAttribute("err_message","验证码不能为空!");
            request.setAttribute("err_detail_message","验证码不能为空!");
            // 验证码错误
        } else if ("2".equalsIgnoreCase(err_code)){
            request.setAttribute("err_message","验证码错误!");
            request.setAttribute("err_detail_message","对不起,验证码错误了!");
            // 检测到非法SQL注入字符
        } else if ("3".equalsIgnoreCase(err_code)){
            request.setAttribute("err_message","SQL注入攻击");
            request.setAttribute("err_detail_message","检测到您的参数存在sql注入字符!请重新输入");
        }else {
            // 失败填充的页面输出信息
            request.setAttribute("err_message","用户名或密码错误");
            request.setAttribute("err_detail_message","用户名或密码错误是不是你有可能忘记了呢?");
        }

        return "errorpage";
    }

    /**
     * 登录页面导航
     * @return
     */
    @GetMapping(value = {"/login"})
    @ApiOperation(value = "登录页面导航")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public String login(){

        return "login";
    }

    /**
     * 注册页面导航
     * @return
     */
    @GetMapping(value = {"/register"})
    @ApiOperation(value = "注册页面导航")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public String register(HttpSession session){

        return "register";
    }



    /**
     * 用户注册请求处理
     * @param user  用户对象
     * @return
     */
    @PostMapping("/register")
    @ApiOperation(value = "用户注册请求处理",consumes = "application/json", produces = "application/json")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    @ResponseBody
    public @ApiIgnore ResponseEntity<ResultMsg> registerMethod(@Valid @RequestBody UserVo user, @ApiIgnore Errors errors,@ApiIgnore HttpSession session){

        // 对象参数校验
        if (errors.hasErrors()) {
            List<ObjectError> oes = errors.getAllErrors();
            for (ObjectError oe : oes) {
                if (oe instanceof FieldError) {
                    FieldError fe = (FieldError) oe;
                    // 添加错误信息到视图
                    return ReturnOperator.createResultMsg("", fe.getDefaultMessage(), ServerStatus.ERROR,
                            new ArrayList(), emptyObject, HttpStatus.OK);
                } else {
                    // 添加错误信息到视图
                    return ReturnOperator.createResultMsg("", oe.getDefaultMessage(), ServerStatus.ERROR,
                            new ArrayList(), emptyObject, HttpStatus.OK);
                }
            }

        }
        // 判断密码和确认密码是否不同
        if (!user.getPassword().equalsIgnoreCase(user.getRepassword())) {
            return ReturnOperator.createResultMsg("", ServerStatus.PASSWORD_REPASSWORD_NOEQURE, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 手机验证码不匹配
        if (!user.getPhoneverifycode().equalsIgnoreCase(String.valueOf(session.getAttribute("phoneverifycode")))) {
            return ReturnOperator.createResultMsg("", "手机验证码错误", ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 用户名+密码 查询用户
        User user_q = userService.queryUserByName(user.getUsername());
        // 查询用户结果校验是否已存在
        if (EmptyUtils.isUserEmpty(user_q)) {
            // 返回信息
            return ReturnOperator.createResultMsg("", ServerStatus.USER_EXISTS, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 密码进行Pbkdf2加密处理
        user.setPassword(new Pbkdf2PasswordEncoder(this.secret).encode(user.getPassword()));
        // 级联添加标志位设置为0
        user.setJltj(0);
        // 角色权限
        user.setRoleId(2);
        // 逻辑删除
        user.setDeleted(0);

        // 添加用户
        User user_new = userService.insert(user);

        if (!EmptyUtils.isUserEmpty(user_new)){
            // 返回信息
            return ReturnOperator.createResultMsg("", ServerStatus.USER_REGISTER_FAILD, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }
        // 返回视图
        return ReturnOperator.createResultMsg(ServerStatus.USER_REGISTER_SUCCESS, "", ServerStatus.OK,
                new ArrayList(), user_new, HttpStatus.OK);
    }

}
